#
#= プロジェクトモデル
#WBS，ガントチャート，カレンダーなどプロジェクト構成オブジェクトの一覧を取得する
#また，テンプレートデータ(テンプレートマスタ）から属性値をコピーする
#
class DatProject < ActiveRecord::Base

  #########################
  # 関連定義
  #########################
  # プロジェクト構成データを所有する(1:多)
  has_many :dat_projectcomps, :foreign_key => "project_id", :dependent=>:destroy
  # プロジェクトユーザーデータを所有する(1:多)
  has_many :dat_projectusers, :foreign_key => "project_id", :dependent=>:destroy

  #########################
  # 検証機能定義
  # （全てのインスタンスで共通の検査項目は、クラスメソッドで定義）
  # （:messageの指定は、言語DBのエラーメッセージ区分に登録されているmsg_cdを指定）
  #########################
  # 未入力検証
  validates_presence_of :project_cd, :project_name, :message=>:cant_be_empty
  # 文字数検証
  validates_length_of :project_cd, :maximum=>100, :too_long=>"too_long,%d"
  validates_length_of :project_name, :maximum=>255, :too_long=>"too_long,%d"
  validates_length_of :end_user_name, :maximum=>255, :allow_nil=>true, :too_long=>"too_long,%d"
  # その他検証


  #
  #=== 検証エラーを記録する
  #
  #開始日、終了日期間の検証エラーを記録する。
  #
def validate
    # 開始日、終了日期間チェック
    if ! start_date.blank? && ! delivery_date.blank?
      errors.add(:start_date, :range_compare_invalid ) if start_date > delivery_date 
      errors.add(:delivery_date, :range_compare_invalid ) if start_date > delivery_date 
    end
  end


  #
  #=== テンプレートデータから属性値をコピーする
  #
  #指定されたテンプレートデータ(テンプレートマスタ）から
  #属性値をコピーする。
  #
  def copyFromTemplate(template)
    for composition in template.mst_compositions
      projectcomp = self.dat_projectcomps.build
      projectcomp.create_user_id = self.create_user_id
      projectcomp.update_user_id = self.update_user_id
      projectcomp.last_operation_kbn = 1
      projectcomp.copyFromTemplate(composition)
    end
  end


  #
  #=== プロジェクト情報取得処理
  #
  #登録済みプロジェクト情報を取得
  #※プロジェクトユーザ情報も同時に取得
  #
  def self.find_project_and_users(project_id, user_id)
    opt = {
      :conditions => ["dat_projects.id = ? AND dat_projectusers.user_id = ? ", project_id, user_id],
      :include    => :dat_projectusers
    }
    find(:first, opt)
  end


  #
  #=== WBSアイテム一覧を返す
  #
  #プロジェクト構成オブジェクトがあれば、
  #そのオブジェクトからWBSアイテムオブジェクトの一覧を出力する。
  #
  def getWbsItemList
    list = Array.new
  
    return list if self.dat_projectcomps.nil?
    return list if self.dat_projectcomps.size <= 0

    self.dat_projectcomps.each do |pc|
      list.push ClsWbsitem.new( pc )
    end

    return list
  end


  #
  #=== プロジェクトアイテム一覧を返す
  #
  #プロジェクト構成オブジェクトがあれば、
  #そのオブジェクトからプロジェクトアイテムオブジェクトの一覧を出力する。
  #
  def getProjectItemList
    list = Array.new

    return list if self.dat_projectcomps.nil?
    return list if self.dat_projectcomps.size <= 0

    projectitem = self.getProjectItemFirst
    while ! projectitem.nil?
      list.push projectitem
      projectitem = self.getProjectItemNext
    end

    return list
  end


  #
  #=== プロジェクトアイテムオブジェクトを返す
  #
  #初期化処理を行う。また、該当プロジェクトのプロジェクト構成オブジェクトがあれば
  #そのオブジェクトからプロジェクトアイテムオブジェクトを出力する。
  #
  def getProjectItemFirst
    self.cur_index = 0
    self.class_word1 = ""
    self.class_word2 = ""
    self.class_word3 = ""

    if self.dat_projectcomps.size > 0
      return self.getProjectItemNext
    else
      return nil
    end
  end


  #
  #=== プロジェクトアイテムオブジェクトを返す
  #
  #現在のインデックスに対応するプロジェクト構成オブジェクトがあれば
  #そのオブジェクトからプロジェクトアイテムオブジェクトを出力する。
  #
  def getProjectItemNext
    return nil if self.dat_projectcomps.size <= 0
    return nil if self.dat_projectcomps.size <= self.cur_index

    projectcomp = self.dat_projectcomps[ self.cur_index ]
    class_word1 = projectcomp.class_word1.nil? ? "" : projectcomp.class_word1
    class_word2 = projectcomp.class_word2.nil? ? "" : projectcomp.class_word2
    class_word3 = projectcomp.class_word3.nil? ? "" : projectcomp.class_word3

    item = nil
    if self.class_word1 != class_word1 && class_word1 != ""
      item = ClsProjectitem.new( true, 0, projectcomp )
      self.class_word1 = class_word1
      self.class_word2 = ""
      self.class_word3 = ""
    elsif  self.class_word2 != class_word2 && class_word2 != ""
      item = ClsProjectitem.new( true, 1, projectcomp )
      self.class_word2 = class_word2
      self.class_word3 = ""
    elsif  self.class_word3 != class_word3 && class_word3 != ""
      item = ClsProjectitem.new( true, 2, projectcomp )
      self.class_word3 = class_word3
    else
      item = ClsProjectitem.new( false, nil, projectcomp )
      self.cur_index += 1
    end

    return item
  end


  #
  #=== プロジェクト構成情報を生成
  #
  #プロジェクト構成オブジェクトがあれば
  #そのオブジェクトからプロジェクト構成情報を出力する。
  #
  def getListedFirst
    self.listed_info = Hash.new
    self.listed_info[:cur_index] = 0
    self.listed_info[:cur_info]  = Hash.new
    self.listed_info[:cur_info][:id] = nil
    self.listed_info[:cur_info][:class_word1] = ""
    self.listed_info[:cur_info][:class_word2] = ""
    self.listed_info[:cur_info][:class_word3] = ""

    if self.dat_projectcomps.size > 0
      return self.getListedNext
    else
      return nil
    end
  end


  #
  #=== プロジェクト構成情報を生成
  #
  #現在のインデックスに対応するプロジェクト構成オブジェクトがあれば
  #そのオブジェクトからプロジェクト構成情報を出力する。
  #
  def getListedNext
    return nil if self.dat_projectcomps.size <= 0
    return nil if self.listed_info.nil?
    return nil if self.dat_projectcomps.size <= self.listed_info[:cur_index]

    projectcomp = self.dat_projectcomps[ self.listed_info[:cur_index] ]
    class_word1 = projectcomp.class_word1.nil? ? "" : projectcomp.class_word1
    class_word2 = projectcomp.class_word2.nil? ? "" : projectcomp.class_word2
    class_word3 = projectcomp.class_word3.nil? ? "" : projectcomp.class_word3
    if self.listed_info[:cur_info][:class_word1] != class_word1 && class_word1 != ""
      self.listed_info[:cur_info][:id]          = projectcomp.id
      self.listed_info[:cur_info][:class_word1] = projectcomp.class_word1
      self.listed_info[:cur_info][:class_word2] = ""
      self.listed_info[:cur_info][:class_word3] = ""
      ret = {
          :ref_id      => self.listed_info[:cur_info][:id],
          :ref_obj     => nil,
          :level       => 0,
          :name        => self.listed_info[:cur_info][:class_word1],
          :class_word1 => self.listed_info[:cur_info][:class_word1],
          :class_word2 => self.listed_info[:cur_info][:class_word2],
          :class_word3 => self.listed_info[:cur_info][:class_word3],
      }
      return ret
    elsif  self.listed_info[:cur_info][:class_word2] != class_word2 && class_word2 != ""
      self.listed_info[:cur_info][:class_word2] = projectcomp.class_word2
      self.listed_info[:cur_info][:class_word3] = ""
      ret = {
          :ref_id      => self.listed_info[:cur_info][:id],
          :ref_obj     => nil,
          :level       => 1,
          :name        => self.listed_info[:cur_info][:class_word2],
          :class_word1 => self.listed_info[:cur_info][:class_word1],
          :class_word2 => self.listed_info[:cur_info][:class_word2],
          :class_word3 => self.listed_info[:cur_info][:class_word3],
      }
      return ret
    elsif  self.listed_info[:cur_info][:class_word3] != class_word3 && class_word3 != ""
      self.listed_info[:cur_info][:class_word3] = projectcomp.class_word3
      ret = {
          :ref_id      => self.listed_info[:cur_info][:id],
          :ref_obj     => nil,
          :level       => 3,
          :name        => self.listed_info[:cur_info][:class_word3],
          :class_word1 => self.listed_info[:cur_info][:class_word1],
          :class_word2 => self.listed_info[:cur_info][:class_word2],
          :class_word3 => self.listed_info[:cur_info][:class_word3],
      }
      return ret
    else
        # プロジェクト構成情報を生成
        ret = {
          :ref_id      => self.listed_info[:cur_info][:id],
          :ref_obj     => projectcomp,
          :level       => 0,
          :name        => projectcomp.item_name,
          :class_word1 => self.listed_info[:cur_info][:class_word1],
          :class_word2 => self.listed_info[:cur_info][:class_word2],
          :class_word3 => self.listed_info[:cur_info][:class_word3],
        }
        self.listed_info[:cur_index] += 1
        return ret
    end
  end


:private
  attr_accessor :listed_info
  attr_accessor :cur_index
  attr_accessor :class_word1
  attr_accessor :class_word2
  attr_accessor :class_word3
end